package com.jiepos.mpos.biz.user.service;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.jiepos.mpos.biz.code.service.MenuButtonService;
import com.jiepos.mpos.common.constant.DBConstant.Table;
import com.jiepos.mpos.common.constant.ExceptionConstant;
import com.jiepos.mpos.common.constant.SystemConstant;
import com.jiepos.mpos.common.dao.LogClientKeyDao;
import com.jiepos.mpos.common.entity.App_Ins_InfEntity;
import com.jiepos.mpos.common.entity.App_MenuButton_InfEntity;
import com.jiepos.mpos.common.entity.App_UserRole_InfEntity;
import com.jiepos.mpos.common.entity.App_User_InfEntity;
import com.jiepos.mpos.core.exception.MposException;
import com.jiepos.mpos.core.service.BaseService;
import com.jiepos.mpos.core.util.RandomValidateCode;
import com.jiepos.mpos.core.util.StringUtils;

/**
 * @ClassName: LoginService
 * @Description: 用户登陆服务层
 * @author 孙永
 * @date 2017年9月26日 下午3:14:40
 */
@Component
public class LoginService extends BaseService{
	
	@Autowired
	private UserService userService;
	@Autowired
	private UserRoleService userRoleService;
	@Autowired
	private AppRoleInfService appRoleInfService;
	@Autowired
	private MenuButtonService menuButtonService;
	@Autowired
	private AppInsInfService appInsInfService;
	@Autowired
	private LogClientKeyDao logClientKeyDao;
	/**
	 * 登陆
	 * @param request
	 * @param loginName 登录账号
	 * @param pwd 登陆密码
	 */
	public void checkLogin(HttpServletRequest request, String loginName, String pwd){
		boolean isRight = RandomValidateCode.checkCode(request);
		/*校验验证码*/
		if(!isRight){
			throw new MposException(ExceptionConstant.USER_LOGIN_CODE_ERROR);
		}
		/*校验用户名和密码*/
		if(StringUtils.isBlank(loginName) || StringUtils.isBlank(pwd)){
			throw new MposException(ExceptionConstant.USER_LOGIN_USER_PWD_EMPTY);
		}
		App_User_InfEntity entity = userService.getUserByLoginName(loginName);
		/*验证用户是否存在*/
		if(entity == null){
			throw new MposException(ExceptionConstant.USER_LOGIN_USER_PWD_ERROR);
		}
		/*状态非启用*/
		if(!SystemConstant.USER_ENABLED.equals(entity.getUser_st())){
			throw new MposException(ExceptionConstant.USER_DISABLED_OR_LOCKED);
		}
		/*验证密码*/
		if(!entity.getPassword().equals(StringUtils.MD5(loginName + pwd))){
			ExceptionConstant exceptionConstant = ExceptionConstant.USER_LOGIN_USER_PWD_ERROR;
			int errorTimes = entity.getCheck_login_count() == null ? 0 : Integer.parseInt(entity.getCheck_login_count());
			entity.setCheck_login_count(String.valueOf(errorTimes + 1));// 错误次数增加1
			if(errorTimes == 4){
				entity.setUser_st(SystemConstant.USER_LOCKED);// 设置冻结状态
				exceptionConstant = ExceptionConstant.USER_LOCKED;
			}
			userService.saveUserInf(entity);// 记录错误次数
			throw new MposException(exceptionConstant);
		}else if(!StringUtils.isBlank(entity.getCheck_login_count())){// 有错误次数但密码正确之后，清空错误次数
			entity.setCheck_login_count(null);
			userService.saveUserInf(entity);
		}
		/*验证角色*/
		App_UserRole_InfEntity userRoleEntity = userRoleService.getUserRoleByUserUuid(entity.getUser_uuid());
		if(userRoleEntity == null || StringUtils.isBlank(userRoleEntity.getRole_uuid())){
			throw new MposException(ExceptionConstant.USER_HAVE_NO_AUTH_USE_SYSTEM);
		}
		/*校验是否首次登陆*/
		if(SystemConstant.USER_NOT_LOGIN.equals(entity.getFirst_login())){
			throw new MposException(ExceptionConstant.USER_LOGIN_FIRST);
		}
		/*登陆成功，记录用户数据*/
		addUserInfoToSession(request, entity, userRoleEntity.getRole_uuid());
	}
	
	/**
	 * 修改默认密码
	 * @param loginName 登陆账号
	 * @param oldPwd 原密码
	 * @param newPwd 新密码
	 */
	public void modifyLoginPwd(String loginName, String oldPwd, String newPwd){
		userService.modifyPwd(loginName, oldPwd, newPwd);
	}
	
	private void addUserInfoToSession(HttpServletRequest request, App_User_InfEntity userEntity, String roleUuid){
		HttpSession session = request.getSession();
		/*查询所属机构*/
		App_Ins_InfEntity insEntity = appInsInfService.getInsInfByUuid(userEntity.getIns_uuid());
		/*查询机构的级别*/
		int insLevel = appInsInfService.getInsLevelByInsUUID(userEntity.getIns_uuid());
		/*用户数据存入session*/
		session.setAttribute(SystemConstant.SESSION_LOGIN_USER, userEntity.getLogin_name());// 添加登陆账号
		session.setAttribute(SystemConstant.SESSION_USER_NAME, userEntity.getUser_name());// 添加真实姓名
		session.setAttribute(SystemConstant.SESSION_USER_UUID, userEntity.getUser_uuid());// 添加用户主键
		session.setAttribute(SystemConstant.SESSION_USER_CATEGORY, userEntity.getUser_category());// 添加用户类别
		session.setAttribute(SystemConstant.SESSION_LOGIN_INS_UUID, userEntity.getIns_uuid());// 添加机构编码
		session.setAttribute(SystemConstant.SESSION_ROLE_UUID, roleUuid);// 添加角色编码
		session.setAttribute(SystemConstant.SESSION_LOGIN_INS_PHONE, insEntity.getPhone());// 添加机构编码
		session.setAttribute(SystemConstant.SESSION_LOGIN_INS_LEVEL, insLevel);//添加用户的机构的级别
		/*查询菜单权限*/
		List<Map<String, Object>> urls = appRoleInfService.getMenuUrlByRoleUuid(roleUuid);
		List<Object> urlList = new ArrayList<>();
		StringBuffer btnUuid = new StringBuffer();
		for(Map<String, Object> url : urls){
			if(url.get("MENU_URL") != null){
				urlList.add(url.get("MENU_URL"));
			}
			if(url.get("MENU_URL1") != null){
				urlList.add(url.get("MENU_URL1"));
			}
			if(url.get("MENU_URL2") != null){
				urlList.add(url.get("MENU_URL2"));
			}
			if(url.get("AUTH_BUTTONS") != null && !StringUtils.isBlank(url.get("AUTH_BUTTONS").toString())){
				btnUuid.append(url.get("AUTH_BUTTONS")).append(",");
			}
		}
		/*查询按钮url*/
		if(btnUuid.length() > 0){
			String btnUuids = "'" + btnUuid.substring(0, btnUuid.length()-1).replaceAll(",", "','") + "'";
			List<App_MenuButton_InfEntity> btnList = menuButtonService.getUrlsByBtnUuids(btnUuids);
			for(App_MenuButton_InfEntity btn : btnList){
				if(!StringUtils.isBlank(btn.getButton_url())){
					urlList.add(btn.getButton_url());
				}
				if(!StringUtils.isBlank(btn.getButton_url1())){
					urlList.add(btn.getButton_url1());
				}
				if(!StringUtils.isBlank(btn.getButton_url2())){
					urlList.add(btn.getButton_url2());
				}
				if(!StringUtils.isBlank(btn.getButton_url3())){
					urlList.add(btn.getButton_url3());
				}
				if(!StringUtils.isBlank(btn.getButton_url4())){
					urlList.add(btn.getButton_url4());
				}
				if(!StringUtils.isBlank(btn.getButton_url5())){
					urlList.add(btn.getButton_url5());
				}
			}
		}
		session.setAttribute(SystemConstant.SESSION_AUTH_LIST, urlList);// 添加菜单或者按钮url
		userService.putEntityToRedis(userEntity.getLogin_name(), userEntity);// 加入缓存
	}
	
	/**
	 * 退出登陆
	 * @param random_number
	 */
	public void logout(String random_number, Map map){
		StringBuffer sb = new StringBuffer();
		List list = new ArrayList<>();
		sb.append(" update ").append(Table.T_APP_LOG_CLIENT_KEY).append(" set rec_st = ?,")
			.append(" last_oper_in = ?,rec_upd_usr_id = ?,rec_upd_ts = ? where random_number = ?");
		list.add(SystemConstant.REC_ST_0);
		list.add(SystemConstant.OPER_DEL);
		list.add(String.valueOf(map.get(SystemConstant.SESSION_LOGIN_USER)));
		list.add(new Timestamp(System.currentTimeMillis()));
		list.add(random_number);
		
		logClientKeyDao.update(sb.toString(), list);
	}
	
	public Map<String, Object> getUserInf(HttpServletRequest request){
		String userUuid = String.valueOf(request.getSession().getAttribute(SystemConstant.SESSION_USER_UUID));
		StringBuffer sql = new StringBuffer();
		/*组装查询用户真实姓名和角色名称*/
		sql.append("SELECT UI.USER_NAME, RI.ROLE_NAME")
		.append("  FROM ").append(Table.T_APP_USER_INF).append(" UI")
		.append("  LEFT JOIN ").append(Table.T_APP_INS_INF).append(" II")
		.append("    ON UI.INS_UUID = II.INS_UUID")
		.append("  LEFT JOIN ").append(Table.T_APP_USERROLE_INF).append(" URI")
		.append("    ON UI.USER_UUID = URI.USER_UUID")
		.append("  LEFT JOIN ").append(Table.T_APP_ROLE_INF).append(" RI")
		.append("    ON URI.ROLE_UUID = RI.ROLE_UUID")
		.append(" WHERE UI.USER_UUID = ?")
		.append("   AND UI.REC_ST = ?");
		List<String> params = new ArrayList<>();
		params.add(userUuid);
		params.add(SystemConstant.NORMAL_STATUS);
		List<Map<String, Object>> result = logClientKeyDao.queryForList(sql.toString(), params);
		if(result != null && !result.isEmpty()){
			Map<String, Object> map = result.get(0);
			/*查询用户所属O单机构名称*/
			String insUuid = String.valueOf(request.getSession().getAttribute(SystemConstant.SESSION_LOGIN_INS_UUID));
			sql = new StringBuffer();
			sql.append("SELECT T.INS_CN_NM")
			.append("  FROM ").append(Table.T_APP_INS_INF).append(" T")
			.append(" WHERE (T.INS_TYPE = '1' OR T.INS_TYPE = '0')")/*查询总公司或者O单机构*/
			.append("   AND ROWNUM = 1")
			.append(" START WITH T.INS_UUID = ?")
			.append("CONNECT BY PRIOR T.SUP_INS_UUID = T.INS_UUID");
			params.clear();
			params.add(insUuid);
			result = logClientKeyDao.queryForList(sql.toString(), params);
			if(result != null && !result.isEmpty()){
				map.putAll(result.get(0));
			}
			return map;
		}
		return new HashMap<>();
	}
	
}
